home *** CD-ROM | disk | FTP | other *** search
- /* $Revision: 1.1 $ */
- /* compile: cc -o glxmotif glxmotif.c -lGLU -lGL -lXm -lXt -lX11 */
- #include <stdlib.h>
- #include <stdio.h>
- #include <Xm/Form.h>
- #include <Xm/Frame.h>
- #include <Xm/DrawingA.h>
- #include <X11/keysym.h>
- #include <GL/gl.h>
- #include <GL/glu.h>
- #include <GL/glx.h>
-
- static int snglBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, None};
- static int dblBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None};
- static String fallbackResources[] = {
- "*glxarea*width: 300", "*glxarea*height: 300",
- "*frame*x: 20", "*frame*y: 20",
- "*frame*topOffset: 20", "*frame*bottomOffset: 20",
- "*frame*rightOffset: 20", "*frame*leftOffset: 20",
- "*frame*shadowType: SHADOW_IN",
- NULL
- };
-
- Display *dpy;
- GLboolean doubleBuffer = GL_TRUE, viewportUpdateNeeded = GL_TRUE, spinning = GL_FALSE;
- XtAppContext app;
- XtWorkProcId workId = 0;
- Widget toplevel, form, frame, glxarea;
-
- void
- updateViewport(Widget w)
- {
- Dimension width, height;
-
- XtVaGetValues(w, XmNwidth, &width, XmNheight, &height, NULL);
- glViewport(0, 0, (GLint) width, (GLint) height);
- viewportUpdateNeeded = GL_FALSE;
- }
-
- void
- draw(Widget w)
- {
- if (viewportUpdateNeeded) updateViewport(w);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glBegin(GL_POLYGON);
- glColor3f(0.0, 0.0, 0.0); glVertex3f(-10.0, -10.0, 0.0);
- glColor3f(0.7, 0.7, 0.7); glVertex3f(10.0, -10.0, 0.0);
- glColor3f(1.0, 1.0, 1.0); glVertex3f(-10.0, 10.0, 0.0);
- glEnd();
- glBegin(GL_POLYGON);
- glColor3f(1.0, 1.0, 0.0); glVertex3f(0.0, -10.0, -10.0);
- glColor3f(0.0, 1.0, 0.7); glVertex3f(0.0, -10.0, 10.0);
- glColor3f(0.0, 0.0, 1.0); glVertex3f(0.0, 5.0, -10.0);
- glEnd();
- glBegin(GL_POLYGON);
- glColor3f(1.0, 1.0, 0.0); glVertex3f(-10.0, 6.0, 4.0);
- glColor3f(1.0, 0.0, 1.0); glVertex3f(-10.0, 3.0, 4.0);
- glColor3f(0.0, 0.0, 1.0); glVertex3f(4.0, -9.0, -10.0);
- glColor3f(1.0, 0.0, 1.0); glVertex3f(4.0, -6.0, -10.0);
- glEnd();
- if (doubleBuffer) glXSwapBuffers(dpy, XtWindow(w));
- glFlush();
- }
-
- void
- expose(Widget w, XtPointer clientData, XtPointer callData)
- {
- draw(w);
- }
-
- void
- resize(Widget w, XtPointer clientData, XtPointer callData)
- {
- XmDrawingAreaCallbackStruct *cd = (XmDrawingAreaCallbackStruct *) callData;
-
- /* don't try OpenGL until window is realized! */
- if (XtIsRealized(w)) updateViewport(w);
- else viewportUpdateNeeded = GL_TRUE;
- }
-
- Boolean
- spin(XtPointer clientData)
- {
- glRotatef(2.5, 1.0, 0.0, 0.0);
- draw(glxarea);
- return False; /* leave work proc active */
- }
-
- void
- input(Widget w, XtPointer clientData, XtPointer callData)
- {
- XmDrawingAreaCallbackStruct *cd = (XmDrawingAreaCallbackStruct *) callData;
- char buffer[1];
- KeySym keysym;
- int rc;
-
- switch (cd->event->type) {
- case KeyRelease:
- /*
- * It is necessary to convert the keycode to a keysym before it is
- * possible to check if it is an escape
- */
- rc = XLookupString((XKeyEvent *) cd->event, buffer, 1, &keysym, NULL);
- switch (keysym) {
- case XK_Up:
- glRotatef(10.0, 0.0, 0.0, 1.0);
- if (!spinning) draw(w);
- break;
- case XK_Down:
- glRotatef(-10.0, 0.0, 0.0, 1.0);
- if (!spinning) draw(w);
- break;
- case XK_Left:
- glRotatef(-10.0, 0.0, 1.0, 0.0);
- if (!spinning) draw(w);
- break;
- case XK_Right:
- glRotatef(10.0, 0.0, 1.0, 0.0);
- if (!spinning) draw(w);
- break;
- case XK_S: case XK_s: /* the S key */
- if (spinning) {
- XtRemoveWorkProc(workId);
- spinning = GL_FALSE;
- } else {
- workId = XtAppAddWorkProc(app, spin, NULL);
- spinning = GL_TRUE;
- }
- break;
- case XK_Escape:
- exit(0);
- }
- break;
- }
- }
-
- void
- map_state_changed(Widget w, XtPointer clientData, XEvent * event, Boolean * cont)
- {
- switch (event->type) {
- case MapNotify:
- if (spinning && workId != 0) workId = XtAppAddWorkProc(app, spin, NULL);
- break;
- case UnmapNotify:
- if (spinning) XtRemoveWorkProc(workId);
- break;
- }
- }
-
- main(int argc, char *argv[])
- {
- XVisualInfo *vi;
- Colormap cmap;
- GLXContext cx;
- int saved_argc;
- String *saved_argv;
-
- toplevel = XtAppInitialize(&app, "Glxmotif", NULL, 0, &argc, argv,
- fallbackResources, NULL, 0);
- dpy = XtDisplay(toplevel);
-
- /* find an OpenGL-capable RGB visual with depth buffer */
- vi = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf);
- if (vi == NULL) {
- vi = glXChooseVisual(dpy, DefaultScreen(dpy), snglBuf);
- if (vi == NULL) XtAppError(app, "no RGB visual with depth buffer");
- doubleBuffer = GL_FALSE;
- }
- /* create an OpenGL rendering context */
- cx = glXCreateContext(dpy, vi, /* no display list sharing */ None, /* favor direct */ GL_TRUE);
- if (cx == NULL) XtAppError(app, "could not create rendering context");
- /* create an X colormap since probably not using default visual */
- cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone);
-
- XtVaSetValues(toplevel, XtNvisual, vi->visual, XtNdepth, vi->depth,
- XtNcolormap, cmap, NULL);
- XtAddEventHandler(toplevel, StructureNotifyMask, False, map_state_changed, NULL);
-
- form = XmCreateForm(toplevel, "form", NULL, 0);
- XtManageChild(form);
-
- frame = XmCreateFrame(form, "frame", NULL, 0);
- XtVaSetValues(frame, XmNbottomAttachment, XmATTACH_FORM,
- XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM,
- XmNrightAttachment, XmATTACH_FORM, NULL);
- XtManageChild(frame);
-
- glxarea = XtCreateManagedWidget("glxarea", xmDrawingAreaWidgetClass, frame, NULL, 0);
- XtAddCallback(glxarea, XmNexposeCallback, expose, NULL);
- XtAddCallback(glxarea, XmNresizeCallback, resize, NULL);
- XtAddCallback(glxarea, XmNinputCallback, input, NULL);
-
- XtRealizeWidget(toplevel);
-
- /* Once widget is realized (ie, associated with a created X window), we
- * can bind the OpenGL rendering context to the window.
- */
- glXMakeCurrent(dpy, XtWindow(glxarea), cx);
-
- /* setup OpenGL state */
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LEQUAL);
- glClearDepth(1.0);
- glClearColor(0.0, 0.0, 0.0, 0.0);
- glLoadIdentity();
- gluPerspective(40.0, 1.0, 10.0, 200.0);
- glTranslatef(0.0, 0.0, -50.0); glRotatef(-58.0, 0.0, 1.0, 0.0);
-
- XtAppMainLoop(app);
- }
-